package com.mpj.yolov12

import android.util.Log
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
import java.net.InetSocketAddress
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.concurrent.thread

/**
 * UDP接收器，用于接收UDP数据包
 */
class UdpReceiver(
    private val listener: OnPacketReceivedListener,
    private val port: Int
) {
    private val TAG = "UdpReceiver"
    private val BUFFER_SIZE = 1500 // 最大UDP包大小

    private var socket: DatagramSocket? = null
    private var receiverThread: Thread? = null
    private val running = AtomicBoolean(false)

    fun stop() {
        running.set(false)

        socket?.close()
        socket = null

        receiverThread?.interrupt()
        receiverThread = null

        Log.i(TAG, "UDP接收器已停止")
    }

    /**
     * 发送具有特定头部的UDP命令到设备
     *
     * @param targetIp 目标设备IP地址
     * @param targetPort 目标设备端口
     * @param payloadData 额外的数据载荷(可选)
     */
    fun sendCommandPacket(targetIp: String, targetPort: Int, payloadData: ByteArray? = null) {
        thread {
            try {
                socket = DatagramSocket(null).apply {
                    reuseAddress = true
                    soTimeout = 1000
                    bind(InetSocketAddress(targetPort))
                }
                // 创建UDP套接字
                // 解析目标IP地址
                val address = InetAddress.getByName(targetIp)

                // 创建命令包头 (0x20, 0x36)
                val header = byteArrayOf((0x20).toByte(), (0x36).toByte())

                // 组合完整的数据包
                val data = if (payloadData != null) {
                    // 如果有额外数据，合并头部和数据
                    header + payloadData
                } else {
                    // 如果没有额外数据，只使用头部
                    header
                }

                // 创建UDP数据包
                var packet = DatagramPacket(data, data.size, address, targetPort)

                // 发送数据包
                socket?.send(packet)

                Log.d(
                    "UDP命令",
                    "已发送命令(0x20, 0x36)到 $targetIp:$targetPort，总长度: ${data.size} 字节"
                )
                while (true) {
                    try {
                        val buffer = ByteArray(1500)
                        packet = DatagramPacket(buffer, buffer.size)
                        socket?.receive(packet)
                        println("rec....")
                        // 提取实际数据
                        val actualData = packet.data.copyOfRange(0, packet.length)
                        // 通知监听器
                        listener.onPacketReceived(
                            actualData,
                            packet.address,
                            packet.port
                        )
                        // 重置数据包
                        packet.length = buffer.size
                    } catch (e: Exception) {
                        println("udp die")
                    }
                }

            } catch (e: Exception) {
                Log.e("UDP命令", "发送命令失败: ${e.message}", e)
            } finally {
                // 关闭套接字
                socket?.close()
            }
        }
    }

}